# -*- coding: utf-8 -*-
"""
core/utils.py

通用工具函数模块
"""

import json
import logging
import os
import chardet

# --- 日志记录配置 ---
def setup_logger(log_file_path="data/logs/system.log", level=logging.INFO):
    """
    配置全局日志记录器

    参数:
        log_file_path (str): 日志文件路径。
        level (int): 日志记录级别。

    返回:
        logging.Logger: 配置好的日志记录器实例。
    """
    log_dir = os.path.dirname(log_file_path)
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    logger = logging.getLogger("EmbedCodeGen")
    logger.setLevel(level)

    # 防止重复添加handler
    if not logger.handlers:
        # 文件处理器
        fh = logging.FileHandler(log_file_path, encoding="utf-8")
        fh.setLevel(level)
        # 控制台处理器
        ch = logging.StreamHandler()
        ch.setLevel(level)

        # 日志格式
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        logger.addHandler(fh)
        logger.addHandler(ch)
    return logger

# 默认初始化一个logger，其他模块可以直接导入使用
logger = setup_logger()

# --- 文件操作 ---
def read_file_content(file_path, default_encoding="utf-8"):
    """
    读取文件内容，自动检测编码（优先尝试默认编码，然后是GBK，最后是chardet）。

    参数:
        file_path (str): 文件路径。
        default_encoding (str): 优先尝试的默认编码。

    返回:
        str: 文件内容，如果读取失败则返回None。
    """
    try:
        with open(file_path, "r", encoding=default_encoding) as f:
            return f.read()
    except UnicodeDecodeError:
        logger.warning(f"使用默认编码 {default_encoding} 读取文件 {file_path} 失败，尝试GBK...")
        try:
            with open(file_path, "r", encoding="gbk") as f:
                return f.read()
        except UnicodeDecodeError:
            logger.warning(f"使用GBK编码读取文件 {file_path} 失败，尝试chardet自动检测...")
            try:
                with open(file_path, "rb") as f_raw:
                    raw_data = f_raw.read()
                detected_encoding = chardet.detect(raw_data)["encoding"]
                if detected_encoding:
                    logger.info(f"Chardet检测到文件 {file_path} 编码为: {detected_encoding}")
                    return raw_data.decode(detected_encoding)
                else:
                    logger.error(f"Chardet未能检测到文件 {file_path} 的编码。")
                    return None
            except Exception as e:
                logger.error(f"使用chardet自动检测编码读取文件 {file_path} 失败: {e}")
                return None
        except Exception as e:
            logger.error(f"使用GBK编码读取文件 {file_path} 时发生其他错误: {e}")
            return None
    except FileNotFoundError:
        logger.error(f"文件未找到: {file_path}")
        return None
    except Exception as e:
        logger.error(f"读取文件 {file_path} 时发生未知错误: {e}")
        return None

def write_file_content(file_path, content, encoding="utf-8"):
    """
    将内容写入文件。

    参数:
        file_path (str): 文件路径。
        content (str): 要写入的内容。
        encoding (str): 文件编码。

    返回:
        bool: 写入成功返回True，否则返回False。
    """
    try:
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        with open(file_path, "w", encoding=encoding) as f:
            f.write(content)
        logger.info(f"内容已成功写入文件: {file_path}")
        return True
    except Exception as e:
        logger.error(f"写入文件 {file_path} 失败: {e}")
        return False

# --- JSON操作 ---
def read_json_file(file_path, encoding="utf-8"):
    """
    读取JSON文件内容。

    参数:
        file_path (str): JSON文件路径。
        encoding (str): 文件编码。

    返回:
        dict/list: 解析后的JSON数据，如果失败则返回None。
    """
    content = read_file_content(file_path, default_encoding=encoding)
    if content:
        try:
            return json.loads(content)
        except json.JSONDecodeError as e:
            logger.error(f"解析JSON文件 {file_path} 失败: {e}")
            return None
    return None

def write_json_file(file_path, data, encoding="utf-8", indent=4):
    """
    将数据写入JSON文件。

    参数:
        file_path (str): JSON文件路径。
        data (dict/list): 要写入的数据。
        encoding (str): 文件编码。
        indent (int): JSON缩进级别。

    返回:
        bool: 写入成功返回True，否则返回False。
    """
    try:
        json_string = json.dumps(data, ensure_ascii=False, indent=indent)
        return write_file_content(file_path, json_string, encoding=encoding)
    except TypeError as e:
        logger.error(f"序列化数据到JSON时失败 (文件: {file_path}): {e}")
        return False

if __name__ == "__main__":
    # 测试日志记录
    logger.info("这是来自utils.py的测试日志信息。")

    # 测试文件读写
    test_text_file = "data/output/test_utils.txt"
    test_content = "你好，世界！\nHello, World!"
    if write_file_content(test_text_file, test_content):
        logger.info(f"测试文件写入成功: {test_text_file}")
        read_back_content = read_file_content(test_text_file)
        if read_back_content:
            logger.info(f"从测试文件读回内容: \n{read_back_content}")
            assert read_back_content == test_content

    # 测试GBK文件读取 (需要手动创建一个GBK编码的文件进行测试)
    # gbk_test_file = "data/input/gbk_sample.txt" # 假设存在此文件
    # write_file_content(gbk_test_file, "你好GBK".encode("gbk").decode("gbk"), encoding="gbk") # 模拟创建
    # gbk_content = read_file_content(gbk_test_file)
    # if gbk_content:
    #     logger.info(f"从GBK测试文件读回内容: {gbk_content}")

    # 测试JSON读写
    test_json_file = "data/output/test_utils.json"
    test_json_data = {"name": "测试", "version": 1.0, "items": [1, 2, 3]}
    if write_json_file(test_json_file, test_json_data):
        logger.info(f"测试JSON文件写入成功: {test_json_file}")
        read_back_json = read_json_file(test_json_file)
        if read_back_json:
            logger.info(f"从测试JSON文件读回数据: {read_back_json}")
            assert read_back_json == test_json_data

    logger.info("utils.py 测试完成。")

